package jmine.tec.script.persistent.repository;

import java.util.HashSet;
import java.util.Set;

import jmine.tec.script.ScriptExecutionContext;
import jmine.tec.script.persistent.dao.ScriptPurposeIdentifier;
import jmine.tec.script.persistent.domain.Script;
import jmine.tec.script.persistent.domain.ScriptPurpose;
import jmine.tec.script.persistent.domain.enumx.BaseScriptPurposeIdentifier;
import jmine.tec.test.Builder;

/**
 * Builder de ScriptLanguage
 * 
 * @author lundberg
 */
public class ScriptPurposeBuilder implements Builder<ScriptPurpose>, Cloneable {

    private ScriptPurposeIdentifier identifier;

    private String mnemonico;

    private String executionContext;

    private String dependencyContext;

    private String validationContext;

    private Set<Script> initScripts = new HashSet<Script>();

    public ScriptPurposeBuilder() {
        this.identifier = BaseScriptPurposeIdentifier.INIT;
        this.mnemonico = "INIT";
    }

    public static ScriptPurposeBuilder aPurpose() {
        return new ScriptPurposeBuilder();
    }

    public static ScriptPurposeBuilder init() {
        return new ScriptPurposeBuilder();
    }

    public static ScriptPurposeBuilder api() {
        return new ScriptPurposeBuilder().identifiedBy(BaseScriptPurposeIdentifier.API).comMnemonico("API");
    }

    public ScriptPurposeBuilder identifiedBy(ScriptPurposeIdentifier identifier) {
        ScriptPurposeBuilder copy = this.copy();
        copy.identifier = identifier;
        return copy;
    }

    public ScriptPurposeBuilder comMnemonico(String mnemonico) {
        ScriptPurposeBuilder copy = this.copy();
        copy.mnemonico = mnemonico;
        return copy;
    }

    public ScriptPurposeBuilder withEnumIdentifier(ScriptPurposeIdentifier identifier) {
        return this.identifiedBy(identifier).comMnemonico(identifier.toString());
    }

    public ScriptPurposeBuilder comContextoDeExecucao(Class<? extends ScriptExecutionContext> context) {
        ScriptPurposeBuilder copy = this.copy();
        copy.executionContext = context.getCanonicalName();
        return copy;
    }

    public ScriptPurposeBuilder comInitScript(Script init) {
        ScriptPurposeBuilder copy = this.copy();
        copy.initScripts = new HashSet<Script>(this.initScripts);
        copy.initScripts.add(init);
        return copy;
    }

    public ScriptPurpose build() {
        ScriptPurpose purpose = new ScriptPurpose();
        purpose.setId(this.identifier.getSystemId());
        purpose.setMnemonico(this.mnemonico);
        purpose.setExecutionContext(this.executionContext);
        purpose.setDependencyContext(this.dependencyContext);
        purpose.setValidationContext(this.validationContext);
        for (Script script : this.initScripts) {
            purpose.addInitScript(script);
        }
        return purpose;
    }

    private ScriptPurposeBuilder copy() {
        try {
            return (ScriptPurposeBuilder) this.clone();
        } catch (CloneNotSupportedException e) {
            throw new RuntimeException(e);
        }
    }
}
